#include "widget.h"
#include "ui_widget.h"

#define MSG_UDP_PORT 6713
#define MSG_TCP_PORT 6713

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget),
    m_uint16Port(MSG_UDP_PORT)
{
    m_strMyName = QString::fromUtf8("ADC2A:리눅스이제원");
    m_pCodecEUCKR = QTextCodec::codecForName("EUC-KR");

    ui->setupUi(this);

    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(msgSend()));
    connect(&receiveSocket, SIGNAL(readyRead()), this, SLOT(msgReceive()));
    connect(&udpSocket, SIGNAL(readyRead()), this, SLOT(udpReceive()));
    connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(udpRefresh()));
    connect(ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(sendListAdd(QListWidgetItem*)));
    connect(ui->listWidget_2, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(sendListRemove(QListWidgetItem*)));
    connect(ui->radioButton_a, SIGNAL(clicked()), this, SLOT(changeGroup()));
    connect(ui->radioButton_b, SIGNAL(clicked()), this, SLOT(changeGroup()));
    connect(ui->radioButton_c, SIGNAL(clicked()), this, SLOT(changeGroup()));
    connect(ui->radioButton_d, SIGNAL(clicked()), this, SLOT(changeGroup()));
    connect(ui->radioButton_e, SIGNAL(clicked()), this, SLOT(changeGroup()));
    connect(ui->radioButton_f, SIGNAL(clicked()), this, SLOT(changeGroup()));

    tcpServer.setParent(this);

    if(!tcpServer.listen(QHostAddress::Any, MSG_TCP_PORT))
    {
        QMessageBox::warning(this, tr("Error"), tr("TcpServer Listen() Fail"));
    }

    switch (m_uint16Port)
    {
    case 6711:
        ui->radioButton_a->click();
        break;

    case 6712:
        ui->radioButton_b->click();
        break;

    case 6713:
        ui->radioButton_c->click();
        break;

    case 6714:
        ui->radioButton_d->click();
        break;

    case 6715:
        ui->radioButton_e->click();
        break;

    case 6716:
        ui->radioButton_f->click();
        break;

    default:
        ui->radioButton_a->click();
        break;
    }
}

Widget::~Widget()
{
    delete ui;
}

void Widget::msgSend()
{
    if (m_mapReceiver.isEmpty()) return;

    QMapIterator<QString, QHostAddress> i(m_mapReceiver);
    QString strMsg;
    strMsg += m_strMyName + "\n";
    strMsg += QString::fromUtf8("(MM/DD(목)PM08:32\n");
    strMsg += QString::fromUtf8("같이 받은분들:");
    while ( i.hasNext() )
    {
        strMsg += i.next().key();
        strMsg += ',';
    }
    strMsg += QString::fromUtf8("\n");
    strMsg += QString::fromUtf8("---------------------------\n");
    strMsg += ui->textEdit_2->toPlainText();

    i.toFront();
    while (i.hasNext())
    {
        sendSocket.connectToHost(i.next().value(), MSG_TCP_PORT);
        sendSocket.write(m_pCodecEUCKR->fromUnicode(strMsg));
        sendSocket.close();
    }

    m_mapReceiver.clear();
    ui->listWidget_2->clear();
    ui->textEdit_2->clear();
}

void Widget::msgReceive()
{
    QByteArray msg;
    msg = receiveSocket.readAll();
    ui->textEdit->setText(m_pCodecEUCKR->toUnicode(msg));
}

void Widget::udpReceive()
{
    while (udpSocket.hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(udpSocket.pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        udpSocket.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);

        if ( ';' == datagram[0] )
        {
            datagram.remove(0, 1);

            if (datagram != m_pCodecEUCKR->fromUnicode(m_strMyName))
            {
                udpResponse();
            }
        }

        if ( '-' == datagram[0] )
        {
            datagram.remove(0, 1);

            m_mapUsers.remove(m_pCodecEUCKR->toUnicode(datagram));
        }
        else
        {
            m_mapUsers.insert(m_pCodecEUCKR->toUnicode(datagram), sender);
        }
    }

    ui->listWidget->clear();

    QMapIterator<QString, QHostAddress> i(m_mapUsers);

    while (i.hasNext())
    {
        ui->listWidget->addItem(i.next().key());
    }
}

void Widget::udpRefresh()
{
    m_mapUsers.clear();
    ui->listWidget->clear();
    QByteArray datagram = m_pCodecEUCKR->fromUnicode(m_strMyName);
    datagram.insert(0, ';');
    udpSocket.writeDatagram(datagram, QHostAddress::Broadcast, m_uint16Port);
}

void Widget::udpResponse()
{
    QByteArray datagram(m_pCodecEUCKR->fromUnicode(m_strMyName));
    udpSocket.writeDatagram(datagram, QHostAddress::Broadcast, m_uint16Port);
}

void Widget::sendListAdd(QListWidgetItem* item)
{
    m_mapReceiver.insert(item->text(), m_mapUsers[item->text()]);
    ui->listWidget_2->addItem(item->text());
}

void Widget::sendListRemove(QListWidgetItem* item)
{
    m_mapReceiver.remove(item->text());
    ui->listWidget_2->removeItemWidget(item);
}

void Widget::on_pushButton_3_clicked()
{
    ui->listWidget_2->clear();
    m_mapReceiver.clear();

    QMapIterator<QString, QHostAddress> i(m_mapUsers);

    while (i.hasNext())
    {
        i.next();
        m_mapReceiver.insert(i.key(), i.value());
        ui->listWidget_2->addItem(i.key());
    }
}

void Widget::on_pushButton_4_clicked()
{
    ui->listWidget_2->clear();
    m_mapReceiver.clear();
}

void Widget::on_pushButton_5_clicked()
{
    ui->textEdit->clear();
}

void Widget::changeGroup()
{
    switch (this->sender()->objectName().toAscii().at(12)) {
    case 'a':
        m_uint16Port = 6711;
        break;

    case 'b':
        m_uint16Port = 6712;
        break;

    case 'c':
        m_uint16Port = 6713;
        break;

    case 'd':
        m_uint16Port = 6714;
        break;

    case 'e':
        m_uint16Port = 6715;
        break;

    case 'f':
        m_uint16Port = 6716;
        break;

    default:
        return;
        break;
    }

    udpSocket.close();

    if(!udpSocket.bind(m_uint16Port))
    {
        QMessageBox::warning(this, tr("Error"), tr("UDP bind() Fail"));
    }

    udpRefresh();
    m_mapReceiver.clear();
}
